home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK2.toast / Development Kits (Disc 2) / QuickDraw GX / Programming Stuff / Sample Code / Printing Samples / Printer Drivers… / LaserWriterIIsc (New GX v1.1) / ChooserSupport.c < prev    next >
Encoding:
Text File  |  1995-04-10  |  11.2 KB  |  394 lines  |  [TEXT/MPS ]

  1. /*---------------------------------------------------------------------------
  2. FILENAME
  3.     ChooserSupport.c
  4.  
  5. DESCRIPTION
  6.     This file contains the C code for the PACK and LDEF routines used by the
  7.     Chooser when the LaserWriter IISC driver is selected in the Chooser.
  8.         
  9. COPYRIGHT
  10.     Copyright Apple Computer, Inc. 1992-1994
  11.     All rights reserved. 
  12.     
  13. INTERFACE ROUTINES:
  14.     Device
  15.     LDEF
  16.  
  17.     12/20/93 - dmh - Sync'd with the shipping 1.0b3 GX driver.
  18.      8/28/94 - dmh - Sync'd with the shipping 1.0.1 GX driver.
  19.      2/23/95 - dh  - Sync'd with the shipping 1.1f1 GX driver.
  20.  
  21. -------------------------------------------------------------------------------- */
  22.  
  23. // Include the standard Mac header files 
  24. #include "MacIncludes.h"
  25.  
  26. // Include the new QuickDraw GX graphics header files 
  27. #include <graphics routines.h>
  28.  
  29. // Include the required Printing Manager header files 
  30. #include <PrintingDrivers.h>
  31.  
  32. #include "LaserSCResources.h"
  33.  
  34. /*********************************************************************************
  35.  *                                         CONSTANTS                                                     *
  36.  *********************************************************************************/
  37.  
  38. // Chooser initialize message selector
  39. #define    initializeMsg            11
  40.  
  41. // Icon Suite support
  42.  
  43. #define    ttNone                    0x0000
  44. #define    ttDisabled                0x0001
  45. #define    ttOffline                0x0002
  46. #define    ttOpen                    0x0003
  47. #define    ttSelected                 0x4000
  48. #define    ttSelectedDisabled    (ttSelected + ttDisabled)
  49. #define    ttSelectedOffline        (ttSelected + ttOffline)
  50. #define    ttSelectedOpen            (ttSelected + ttOpen)
  51.  
  52. #define    ttLabel0                    0x0000
  53. #define    ttLabel1                    0x0100
  54. #define    ttLabel2                    0x0200
  55. #define    ttLabel3                    0x0300
  56. #define    ttLabel4                    0x0400
  57. #define    ttLabel5                    0x0500
  58. #define    ttLabel6                    0x0600
  59. #define    ttLabel7                    0x0700
  60.  
  61.  
  62. /*********************************************************************************
  63.  *                                    INLINE DECLARATIONS                                            *
  64. **********************************************************************************/
  65.  
  66. pascal OSErr PlotIconSuite(const Rect * theRect, short align, short iconTransform, Handle cIcon)
  67.     = {0x303C, 0x0603, 0xABC9};
  68.  
  69. pascal void OldDrawText(const void *textBuf,short firstByte,short byteCount)
  70.     = 0xA885; 
  71.  
  72.  
  73. /***************************************************************************************
  74. *                                         INTERFACE ROUTINES                                                     *
  75. ***************************************************************************************/                        
  76.  
  77.  
  78. /****************************************************************************************
  79.  
  80.                             Device
  81.                             
  82.     function:
  83.                 This routine is the interface routine for the Chooser PACK.  This is the
  84.                 routine the Chooser calls to perform the Chooser functions for the 
  85.                 LaserWriter IISC driver.
  86.                 
  87.     parameters:                
  88.                 message        specifies which Chooser function to perform    
  89.                 caller        equals 1; specifies the caller is the Chooser
  90.                 objName        name of the selected device
  91.                 zoneName        zone name for AppleTalk devices
  92.                 theList        the list of names
  93.                 p2                parameter used depending upon message value
  94.                 
  95.     returns:
  96.                 OSErr
  97.     
  98. ****************************************************************************************/
  99. pascal OSErr Device(    short         message, 
  100.                             short         caller, 
  101.                             StringPtr     objName,
  102.                             StringPtr    zoneName, 
  103.                             ListHandle    theList, 
  104.                             long            p2)
  105. {
  106.     
  107.     OSErr            anErr = noErr;
  108.     extern Str31     gDriverName;
  109.     StringPtr        pDriverName = (StringPtr)&gDriverName;
  110.     extern gxJob    gJob;
  111.     gxJob                *pJob = &gJob;
  112.     
  113.     // start up GX to begin with
  114.     if (message == initializeMsg)
  115.     {
  116.         FCBPBRec        pb;
  117.         long            theVersion;
  118.  
  119.     /*
  120.         Get the name of our driver for GXHandleChooserMessage.
  121.         (The user may have renamed us.)
  122.     */
  123.         pb.ioCompletion     = nil;
  124.         pb.ioNamePtr         = pDriverName;
  125.         pb.ioVRefNum         = 0;
  126.         pb.ioRefNum         = CurResFile();
  127.         pb.ioFCBIndx         = 0;
  128.         anErr = PBGetFCBInfo(&pb, false);
  129.  
  130.     /*
  131.         Clear *pJob, because it hasn't been initialized yet.  That doesn't
  132.         happen until we pass GXHandleChooserMessage an initializeMsg.
  133.     */
  134.         *pJob = nil;
  135.  
  136.     /*
  137.         Since we rely on gxSetupPageImageData, which is
  138.         only available in QDGX 1.1 or later, don't allow
  139.         the user to create DTPs if we're running on
  140.         anything less.  In that case, put up a dialog
  141.         and do nothing else.
  142.     */
  143.         if (!anErr)
  144.             if ((Gestalt(gestaltGXVersion, &theVersion) != noErr) || (theVersion < 0x00010100))
  145.             {
  146.                 InitCursor();
  147.                 ParamText(pDriverName, "\p", "\p", "\p");
  148.                 StopAlert(kBadVersionDLOG , nil);
  149.                 ParamText("\p", "\p", "\p", "\p");
  150.                 return gxDriverVersionErr;
  151.             }
  152.  
  153.     /*
  154.         We need to initialize GX printing so that we can call
  155.         GXHandleChooserMessage.  Since printing requires a graphics
  156.         client, call GXEnterGraphics first.  If there are errors,
  157.         (for example, due to memory limitations), post an alert.
  158.     */
  159.         if (anErr == noErr)
  160.         {
  161.             GXEnterGraphics();
  162.             anErr = GXGetGraphicsError(nil);
  163.             if (anErr == noErr)
  164.             {
  165.                 anErr = GXInitPrinting();
  166.                 if (anErr != noErr)
  167.                     GXExitGraphics();
  168.             }
  169.                 
  170.             if (anErr != noErr)
  171.                 StopAlert(-4095, nil);
  172.         }
  173.     }
  174.  
  175. /*
  176.     If the Chooser hasn't created a job yet, do nothing unless we were
  177.     sent an initializeMsg.  In its default implementation of
  178.     GXHandleChooserMessage, QuickDraw GX will create the job for our
  179.     driver when it receives an initializeMsg.  It will store a reference
  180.     to it in our pJob pointer.
  181.     
  182.     For all other messages, if a job has been created, call
  183.     GXHandleChooserMessage to handle things.
  184. */
  185.     if (anErr == noErr)
  186.     {
  187.         if ((*pJob != nil) || (message == initializeMsg))
  188.         {
  189.             anErr = GXHandleChooserMessage(pJob, pDriverName, message, caller, objName, zoneName, theList, p2);
  190.     
  191.         /*
  192.             If we just got a terminateMsg, and p2 is also terminateMsg, the
  193.             Chooser is closing.  QuickDraw GX just disposed of the gxJob it
  194.             created earlier when GXHandleChooserMessage was passed
  195.             initializeMsg, so we just need to call GXExitPrinting and
  196.             GXExitGraphics to clean up.
  197.             
  198.             Note that we must test the p2 parameter, because the Chooser
  199.             can also send terminateMsg when it wants to empty the device
  200.             list, but not dispose of us.  For example, this will happen
  201.             when the user turns off AppleTalk in the Chooser.
  202.         */
  203.             if ( (message == terminateMsg) && (p2 == terminateMsg) )
  204.             {
  205.                 GXExitPrinting();
  206.                 GXExitGraphics();
  207.             }
  208.         }
  209.     }
  210.         
  211.     return(anErr);
  212.     
  213. }
  214. /* Device */
  215.  
  216.  
  217.  
  218. /****************************************************************************************
  219.  
  220.                             LDEF
  221.                             
  222.     function:
  223.                 This routine is the LDEF fro the Chooser PACK.  It handles drawing the device
  224.                 list contents.  The LDEF works in two modes:
  225.                     - if the first two characters of the cell are valid AppleTalk NBP names (ie, not ≈ ≈)
  226.                       then the LDEF is just a basic text LDEF
  227.                     - otherwise, it assumes the data is part of a PortListRec, which is
  228.                       a structure for icons with text underneath
  229.                             
  230.     parameters:                
  231.                 message        what operation to perform on the list    
  232.                 select        is this cell to be selected or not?
  233.                 theRect        rectangle of this cell, clipped to window
  234.                 theCell        which cell this is
  235.                 dataOffset    offset into data for this cell
  236.                 dataLen        length of data for this cell
  237.                 theList        the list to act upon
  238.                 
  239.     returns:
  240.                 None
  241.     
  242. ****************************************************************************************/
  243. pascal void LDEF(
  244.     short         message,
  245.     Boolean        select,
  246.     Rect            *theRect,
  247.     Cell            theCell,
  248.     short            dataOffset,
  249.     short            dataLen,
  250.     ListHandle    theList)
  251. {
  252.     #pragma unused (theCell, dataLen)
  253.  
  254.     gxPortListRec        theCellContents;
  255.     Rect                    iconRect;
  256.     unsigned char        hiliteMode;
  257.     
  258.     switch (message)
  259.     {
  260.         case lDrawMsg:
  261.         case lHiliteMsg:
  262.         
  263.             // save the data to avoid locking things down
  264.             if (dataLen > sizeof(theCellContents) )
  265.                 dataLen = sizeof(theCellContents);
  266.             BlockMove(((*(**theList).cells) + dataOffset), &theCellContents, dataLen );
  267.             
  268.             // draw the cell as an icon, but only if we see our magic marker at the front
  269.             if ( (theCellContents.firstMarker == '≈') && (theCellContents.secondMarker == '≈') )
  270.                 {
  271.                 // center the icon rect on the list with a top margin of 10 pixels
  272.                 iconRect.top = theRect->top + 10;
  273.                 iconRect.left = theRect->left + ((theRect->right - theRect->left) >> 1) - 16;
  274.                 iconRect.bottom = iconRect.top + 32;
  275.                 iconRect.right = iconRect.left + 32;
  276.                 
  277.                 
  278.                 // draw the icon
  279.                 if (theCellContents.iconSuiteHandle != nil)
  280.                     PlotIconSuite(&iconRect,
  281.                             ttNone, (select) ? ttSelected: ttNone,
  282.                             theCellContents.iconSuiteHandle);
  283.                             
  284.                 // Get the general area under the icon in which to draw the label
  285.                 iconRect.left = theRect->left + 2;
  286.                 iconRect.right = iconRect.left + (**theList).cellSize.h - 2;
  287.                 iconRect.top = iconRect.bottom + 2;
  288.                 iconRect.bottom = theRect->bottom;
  289.     
  290.                 // use a nice small font for the label            
  291.                 TextFont(applFont);
  292.                 TextSize(9);
  293.                 
  294.                     {
  295.                     short        labelWidth;
  296.                     short        rectWidth;
  297.                     short        labelHeight;
  298.                     FontInfo    theInfo;
  299.                 
  300.                     // Get rid of any text that was there before
  301.                     EraseRect(&iconRect);
  302.                     iconRect.top += 2;
  303.                     
  304.                     // compute the height of the label                    
  305.                     GetFontInfo(&theInfo);
  306.                     labelHeight = theInfo.ascent + theInfo.leading;
  307.                     
  308.                     // compute where to draw the text
  309.                     iconRect.bottom = iconRect.top + labelHeight;
  310.                     rectWidth = iconRect.right-iconRect.left;
  311.                     
  312.                     // truncate the string to fit within the box
  313.                     TruncString(rectWidth, theCellContents.iconName, smTruncEnd);
  314.                     
  315.                     // compute the new width of the string
  316.                     labelWidth = StringWidth(theCellContents.iconName);
  317.                     
  318.                     // center the string, draw it
  319.                     iconRect.left += (rectWidth >> 1) - (labelWidth >> 1);
  320.                     MoveTo(iconRect.left, iconRect.bottom);
  321.                     DrawString(theCellContents.iconName);
  322.                     
  323.                     if (select)
  324.                         {
  325.                         // compute right and lower edge of box bounding the text we just drew
  326.                         iconRect.right = iconRect.left + labelWidth;
  327.                         iconRect.bottom += theInfo.descent;
  328.                         
  329.                         // outset it, and invert it to select it
  330.                         InsetRect(&iconRect, -1, -1);
  331.                         hiliteMode = LMGetHiliteMode();
  332.                         BitClr(&hiliteMode, pHiliteBit);
  333.                         LMSetHiliteMode(hiliteMode);
  334.                         InvertRect(&iconRect);
  335.                         }
  336.                     }
  337.                     
  338.                 TextFont(applFont);
  339.                 TextSize(0);
  340.                 }
  341.             else
  342.                 {
  343.                 // how boring!  It's only text
  344.                 FontInfo    theInfo;
  345.                 Rect        ourRect;
  346.                 short        cellWidth;
  347.                 
  348.                 // add a margin to the rectangle
  349.                 ourRect = *theRect;
  350.                 ourRect.left += 4;
  351.                 --ourRect.right;
  352.                 cellWidth = ourRect.right - ourRect.left;
  353.                 
  354.                 // erase the rectangle
  355.                 GetFontInfo(&theInfo);
  356.                 EraseRect(theRect);
  357.                 MoveTo(ourRect.left, ourRect.bottom - theInfo.descent);
  358.                 
  359.                 // hey, you can't park that string here -- it's too big!
  360.                 if (TextWidth((Ptr) &theCellContents, 0, dataLen) > cellWidth )
  361.                     {
  362.                     // condense the text first
  363.                     TextFace(condense);
  364.                     
  365.                     // then truncate afterwards
  366.                     TruncText(cellWidth, (Ptr) &theCellContents, &dataLen, smTruncEnd);
  367.                     }
  368.                     
  369.                 // those darn other languages!
  370.                 if (GetSysJust() == teJustRight)
  371.                     Move(cellWidth-TextWidth((Ptr) &theCellContents, 0, dataLen) , 0);
  372.                     
  373.                 OldDrawText((Ptr) &theCellContents, 0, dataLen);
  374.                 
  375.                 // if selected, invert it
  376.                 if (select)
  377.                     {
  378.                     hiliteMode = LMGetHiliteMode();
  379.                     BitClr(&hiliteMode, pHiliteBit);
  380.                     LMSetHiliteMode(hiliteMode);
  381.                     InvertRect(theRect);
  382.                     }
  383.                     
  384.                 // normal text again
  385.                 TextFace(normal);
  386.                 }
  387.                 
  388.             break;
  389.             
  390.         } // switch
  391.         
  392. }
  393. /* LDEF */
  394.